package service.facade.admin;

import application.MySession;
import application.util.AppUtils;
import dao.cms.UrlAlreadyExistsException;
import dao.inte.CmsPageRepository;
import dao.inte.UserRepository;
import domain.User;
import domain.cms.AbstractPage;
import domain.cms.CmsHomePage;
import domain.cms.CmsPage;
import exceptions.DeleteException;
import org.springframework.transaction.annotation.Transactional;
import service.ConfigurationService;
import service.ILuceneIndexRebuilder;

import javax.inject.Inject;
import javax.persistence.NoResultException;
import java.io.File;
import java.util.List;
import java.util.logging.Logger;

@Transactional
public class CmsAdminServiceImpl implements CmsAdminService {

    private CmsPageRepository cmsPageRepository;
    private UserRepository userRepository;
    private ConfigurationService configurationService;
    @Inject
    private MySession mySession;
    @Inject
    ILuceneIndexRebuilder luceneIndexer;
    private static Logger logger = Logger.getLogger(CmsAdminServiceImpl.class.getName());

    public CmsAdminServiceImpl() {
    }

    public CmsAdminServiceImpl(CmsPageRepository cmsPageRepository, ConfigurationService configurationService, UserRepository userRepository) {
        this.cmsPageRepository = cmsPageRepository;
        this.configurationService = configurationService;
        this.userRepository = userRepository;
    }

    public List<File> getUploadFiles() {
        return null;
    }

    public CmsPage createCmsSection() throws Exception {
        CmsPage cmsPage = createNewPage();
        return cmsPageRepository.save(cmsPage);
    }

    private CmsPage createNewPage() throws Exception {
        User currentUser = userRepository.findById(mySession.getId());
        CmsPage page = new CmsPage(currentUser);
        if (!isUrlUnique(page)) {
            page.setUrl(page.getUrl() + "-" + AppUtils.randomString(10, 10));
        }
        if (!isUrlUnique(page)) {
            throw new Exception("ERROR" + page + " " + page.getUrl() + " " + page.getId());
        }
        return page;
    }

    public CmsPage addChild(CmsPage page) throws Exception {
        CmsPage parent = cmsPageRepository.findById(page.getId());
        CmsPage child = createNewPage();
        parent.addChild(child);
        child.setParent(parent);
        return cmsPageRepository.save(child);
    }

    public CmsHomePage getHomePage() {
        return configurationService.getCmsHomePage();
    }

    public void removePage(AbstractPage page) throws DeleteException, Exception {
        if (page instanceof CmsPage) {
            CmsPage pageNew = cmsPageRepository.findById(page.getId());
            if (pageNew.getChilds().size() == 0) {
                cmsPageRepository.delete(pageNew);
            } else {
                throw new DeleteException("Page has child");
            }
        } else {
            throw new DeleteException("Page cannot be deleted");
        }
    }

    public List<CmsPage> getSections() {
        return cmsPageRepository.findRoots();
    }

    public <T extends AbstractPage> void updateCmsPage(T page) throws UrlAlreadyExistsException, Exception {

        if (!isUrlUnique(page)) {
            throw new UrlAlreadyExistsException();
        }
        if (page instanceof CmsPage) {

            cmsPageRepository.save((CmsPage) page);
        }

        if (page instanceof CmsHomePage) {
            configurationService.updateCmsHomePage((CmsHomePage) page);
        }
        reindexEntity(page);
    }

    private <T extends AbstractPage> boolean isUrlUnique(T page) {
        try {
            if (cmsPageRepository.findByUrl(page.getUrl()).getId().equals(page.getId())) {
                return true;
            } else {
                return false;
            }
        } catch (NoResultException e) {

            logger.fine("OK, URL is Unique");
            return true;
        }

    }

    private <T extends AbstractPage> void reindexEntity(T page) throws Exception {
        luceneIndexer.reindexEntity(page);
    }

    public void setMySession(MySession mySession) {
        this.mySession = mySession;
    }

    public void changeCmsUrl(CmsPage page, String newUrl, Boolean keepOldUrl) throws Exception {
        if (keepOldUrl) {
            page.addOldCmsUrl(page.getUrl());
        }
        page.setUrl(newUrl);
        cmsPageRepository.save(page);
    }

    public void deleteOldUrl(CmsPage page, String url) throws Exception {
        page.removeOldCmsUrl(url);
        cmsPageRepository.save(page);
    }

}
